package com.easylinkin.linkappapi.ruleengine.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.alarm.entity.AlarmPersonContact;
import com.easylinkin.linkappapi.alarm.entity.AlarmProcess;
import com.easylinkin.linkappapi.alarm.entity.AlarmTemplate;
import com.easylinkin.linkappapi.alarm.mapper.AlarmProcessMapper;
import com.easylinkin.linkappapi.alarm.mapper.AlarmTemplateMapper;
import com.easylinkin.linkappapi.alarm.service.AlarmPersonContactService;
import com.easylinkin.linkappapi.alarm.service.AlarmProcessService;
import com.easylinkin.linkappapi.common.constant.CommonConstant;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.service.DeviceService;
import com.easylinkin.linkappapi.intelligentrule.entity.IntelligentRuleExpression;
import com.easylinkin.linkappapi.intelligentrule.mapper.IntelligentRuleExpressionMapper;
import com.easylinkin.linkappapi.linkage.entity.LinkageConfigRefDownDevice;
import com.easylinkin.linkappapi.linkage.entity.LinkageConfigRelateServiceParm;
import com.easylinkin.linkappapi.linkage.mapper.LinkageConfigRefDownDeviceMapper;
import com.easylinkin.linkappapi.linkage.mapper.LinkageConfigRelateServiceParmMapper;
import com.easylinkin.linkappapi.ruleengine.constant.RuleEngineConstant;
import com.easylinkin.linkappapi.ruleengine.entity.*;
import com.easylinkin.linkappapi.ruleengine.mapper.*;
import com.easylinkin.linkappapi.ruleengine.service.RuleConditionService;
import com.easylinkin.linkappapi.ruleengine.service.RuleEngineService;
import com.easylinkin.linkappapi.ruleengine.service.RuleExecutionService;
import com.easylinkin.linkappapi.ruleengine.service.RuleTriggerService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;

import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import com.easylinkin.linkappapi.taskscheduler.entity.JobEntity;
import com.easylinkin.linkappapi.taskscheduler.mapper.JobEntityMapper;
import com.easylinkin.linkappapi.taskscheduler.service.TaskSchedulerService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * <p>
 * 智能规则引擎 服务实现类
 * </p>
 *
 * @author TongJie
 * @since 2020-08-24
 */
@Service
public class RuleEngineServiceImpl extends ServiceImpl<RuleEngineMapper, RuleEngine> implements RuleEngineService, Job {


    private static final Logger LOGGER = LoggerFactory.getLogger(RuleEngineServiceImpl.class);

    @Resource
    private CommonService commonService;
    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;
    @Resource
    private RuleTriggerService ruleTriggerService;
    @Resource
    private RuleConditionService ruleConditionService;
    @Resource
    private RuleExecutionService ruleExecutionService;
    @Resource
    private AlarmPersonContactService alarmPersonContactService;
    @Resource
    private RuleTriggerMapper ruleTriggerMapper;
    @Resource
    JobEntityMapper jobEntityMapper;
    @Resource
    TaskSchedulerService taskSchedulerService;
    @Resource
    RuleConditionMapper ruleConditionMapper;
    @Resource
    RuleExecutionMapper ruleExecutionMapper;
    @Resource
    AlarmTemplateMapper alarmTemplateMapper;
    @Resource
    LinkageConfigRelateServiceParmMapper linkageConfigRelateServiceParmMapper;
    @Resource
    RuleTriggerRefDeviceMapper ruleTriggerRefDeviceMapper;
    @Resource
    LinkageConfigRefDownDeviceMapper linkageConfigRefDownDeviceMapper;
    @Resource
    IntelligentRuleExpressionMapper intelligentRuleExpressionMapper;
    @Resource
    RuleExecutionRefAlarmPersonContactMapper ruleExecutionRefAlarmPersonContactMapper;
    @Resource
    DeviceService deviceService;
    @Value("${message.signName}")
    String signName;
    @Resource
    IAcsClient acsClient;
    private static String TEMPLATEPREFIX="模板-";


    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        // 取得job名称
        String jobName = jobDetail.getKey().getName();
        String jobGroup = jobDetail.getKey().getGroup();
        RuleTrigger ruleTrigger = ruleTriggerService.getById(jobName);
        if (ruleTrigger == null || ObjectUtils.isEmpty(ruleTrigger.getRuleEngineId())) {
            LOGGER.info("定时任务查得对应的规则引擎id为空,任务分组：{}，任务名称：{}，任务触发时间：{}", jobGroup, jobName, DateUtil.getYYYYMMDDHHMMSSDate(new Date()));
            return;
        }
        QueryWrapper qw = new QueryWrapper();
        qw.eq("id", ruleTrigger.getRuleEngineId());
        qw.eq("status", RuleEngineConstant.STATUS_ENABLE);
        RuleEngine ruleEngine = getOne(qw);
        if (ObjectUtils.isEmpty(ruleEngine)) {
//            LOGGER.info("定时任务查得对应的开启的规则引擎为空,任务分组：{}，任务名称：{}，任务触发时间：{}", jobGroup, jobName, DateUtil.getYYYYMMDDHHMMSSDate(new Date()));
            return;
        }
        String tenantId = ruleEngine.getTenantId();
        LOGGER.info("ruleEngine开启的定时任务，任务分组：{}，任务名称：{}，任务触发时间：{}", jobGroup, jobName, DateUtil.getYYYYMMDDHHMMSSDate(new Date()));
        qw = new QueryWrapper();
        qw.eq("rule_engine_id", ruleEngine.getId());
        qw.orderByAsc("sort_flag");
        List<RuleExecution> ruleExecutions = ruleExecutionService.list(qw);
        for (RuleExecution ruleExecution : ruleExecutions) {
            ruleExecution.setRuleEngine(ruleEngine);
            ruleExecution.setTenantId(tenantId);
            ruleExecutionService.generateLinkage(ruleExecution);
        }
    }


    /**
     * 触发 规则引擎 流水线 触发器-->条件器-->执行器
     *
     * @param device 设备vo
     * @param data
     */
    @Override
    public void triggerAssemblyLine(Device device, Object data) {

//        通过触发器 过滤出满足条件的 相关联的规则引擎id列表
        Set<String> meetedRuleEngineIds = ruleTriggerService.getMeetRuleTriggerRuleEngineIds(device, data);
        if (ObjectUtils.isEmpty(meetedRuleEngineIds)) {
            return;
        }

        QueryWrapper qw = new QueryWrapper();
        qw.in("id", meetedRuleEngineIds);
        qw.eq("status", 1);
        qw.select("id");
        List<RuleEngine> ruleEngineList = list(qw);
        meetedRuleEngineIds = ruleEngineList.stream().map(RuleEngine::getId).collect(Collectors.toSet());

        if (ObjectUtils.isEmpty(meetedRuleEngineIds)) {
            LOGGER.info("不满足触发器条件，device:{}", device);
            return;
        }
//        通过条件器 过滤出满足条件的 相关联的规则引擎id列表
        meetedRuleEngineIds = ruleConditionService.getMeetRuleConditionRuleEngineIds(meetedRuleEngineIds);

        if (ObjectUtils.isEmpty(meetedRuleEngineIds)) {
            LOGGER.info("不满足触发器条件，device:{}", device);
            return;
        }

        ruleExecutionService.execute(meetedRuleEngineIds, device);


    }


    @Override
    public void add(RuleEngine ruleEngine) {
        validParamRequired(ruleEngine);
        validParamFormat(ruleEngine);
        validRepeat(ruleEngine);
        commonService.setCreateAndModifyInfo(ruleEngine);
        LinkappUser user = linkappUserContextProducer.getCurrent();
        ruleEngine.setTenantId(user.getTenantId());
        save(ruleEngine);

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setDetailConfig(RuleEngine ruleEngine) {
        Assert.notNull(ruleEngine, "规则引擎参数为空");
        Assert.hasLength(ruleEngine.getId(), "规则引擎id参数为空");
        RuleEngine ruleEngineOld = getById(ruleEngine.getId());
        Assert.notNull(ruleEngineOld, "查得原规则引擎不存在");
        ruleEngine.setDescription(ruleEngineOld.getDescription());
        commonService.setModifyInfo(ruleEngine);
        updateById(ruleEngine);

        QueryWrapper qw = new QueryWrapper();
        qw.eq("rule_engine_id", ruleEngine.getId());

//        清除旧的关联
        ruleTriggerService.deleteBatch(ruleTriggerService.list(qw));
        ruleConditionService.deleteBatch(ruleConditionService.list(qw));
        ruleExecutionService.deleteBatch(ruleExecutionService.list(qw));

        List<RuleTrigger> ruleTriggers = ruleEngine.getRuleTriggers() != null ? ruleEngine.getRuleTriggers() : new ArrayList<>();

        for (RuleTrigger ruleTrigger : ruleTriggers) {
            ruleTrigger.setRuleEngineId(ruleEngine.getId());
            ruleTriggerService.add(ruleTrigger);
        }
        List<RuleCondition> ruleConditions = ruleEngine.getRuleConditions() != null ? ruleEngine.getRuleConditions() : new ArrayList<>();
        for (RuleCondition ruleCondition : ruleConditions) {
            ruleCondition.setRuleEngineId(ruleEngine.getId());
            ruleConditionService.add(ruleCondition);
        }
        List<RuleExecution> ruleExecutions = ruleEngine.getRuleExecutions() != null ? ruleEngine.getRuleExecutions() : new ArrayList<>();
        for (RuleExecution ruleExecution : ruleExecutions) {
            ruleExecution.setRuleEngineId(ruleEngine.getId());
            ruleExecutionService.add(ruleExecution);
        }

    }

    /**
     * 校验重复
     */
    private void validRepeat(RuleEngine ruleEngine) {
        QueryWrapper<RuleEngine> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", ruleEngine.getName());
        queryWrapper.eq("tenant_id", linkappUserContextProducer.getNotNullCurrent().getTenantId());
        List<RuleEngine> list = baseMapper.selectList(queryWrapper);
        if (list.size() == 0) {
            return;
        }
        if (list.size() > 1) {
            throw new BusinessException("规则引擎名称有重复");
        }
        if (StringUtils.isEmpty(ruleEngine.getId())) {
            throw new BusinessException("规则引擎名称已存在");
        }
        if (!ruleEngine.getId().equals(list.get(0).getId())) {
            throw new BusinessException("规则引擎名称已存在");
        }

    }


    /**
     * 校验参数必填
     */
    private void validParamRequired(RuleEngine ruleEngine) {
        Assert.notNull(ruleEngine, "参数为空");
        Assert.isTrue(StringUtils.isNotBlank(ruleEngine.getName()), "名称为空");
        Assert.hasLength(ruleEngine.getSpaceId(), "参数空间为空");

    }

    /**
     * 校验参数格式
     */
    private void validParamFormat(RuleEngine ruleEngine) {
        Assert.isTrue(ruleEngine.getName() == null || ruleEngine.getName().length() <= 32, "名称超长");
        Assert.isTrue(ruleEngine.getDescription() == null || ruleEngine.getDescription().length() <= 255, "规则引擎描述超长");
        Assert.isTrue(ruleEngine.getTenantId() == null || ruleEngine.getTenantId().length() <= 32, "租户id超长");
        Assert.isTrue(ruleEngine.getSpaceId() == null || ruleEngine.getSpaceId().length() <= 32, "空间id超长");
    }

    @Override
    public List<RuleEngine> getRuleEngines(RuleEngine ruleEngine) {
        ruleEngine.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        List<String> spacesIds = commonService.getCurrentUserSpaceIds();
        return baseMapper.getRuleEngines(ruleEngine, spacesIds);
    }

    @Override
    public IPage<RuleEngine> getRuleEngines(Page page, RuleEngine ruleEngine) {
        ruleEngine.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        List<String> spacesIds = commonService.getCurrentUserSpaceIds();
        return baseMapper.getRuleEngines(page, ruleEngine, spacesIds);
    }

    @Override
    public RuleEngine getRuleEngine(String id) {
        Assert.hasLength(id, "id 不能为空");
        RuleEngine ruleEngine = getById(id);
        if (ruleEngine == null) {
            return null;
        }
        RuleTrigger ruleTrigger = new RuleTrigger();
        RuleCondition ruleCondition = new RuleCondition();
        RuleExecution ruleExecution = new RuleExecution();

        ruleTrigger.setRuleEngineId(ruleEngine.getId());
        ruleCondition.setRuleEngineId(ruleEngine.getId());
        ruleExecution.setRuleEngineId(ruleEngine.getId());

        ruleEngine.setRuleTriggers(ruleTriggerService.getRuleTriggersAndExpressions(ruleTrigger));
        ruleEngine.setRuleConditions(ruleConditionService.getRuleConditionWithExpressions(ruleCondition));
        ruleEngine.setRuleExecutions(ruleExecutionService.getRuleExecutionDetails(ruleExecution));

        return ruleEngine;
    }


    @Override
    public void updateRuleEngine(RuleEngine ruleEngine) {
        Assert.notNull(ruleEngine, "参数为空");
        RuleEngine originRuleEngine = getById(ruleEngine.getId());
        Assert.notNull(originRuleEngine, "原规则引擎不存在");
        validRepeat(ruleEngine);
        validParamFormat(ruleEngine);
        commonService.setModifyInfo(ruleEngine);
        updateById(ruleEngine);
    }

    @Override
    public void trigger(RuleEngine ruleEngine) {
        Assert.notNull(ruleEngine, "参数为空");
        Assert.hasLength(ruleEngine.getId(), "参数id 为空");

        ruleEngine = getById(ruleEngine.getId());
        Assert.notNull(ruleEngine, "查得规则引擎为空，id： " + ruleEngine.getId());
        String tenantId = ruleEngine.getTenantId();

        QueryWrapper<RuleExecution> qw = new QueryWrapper<>();
        qw.select("id", "delay_time", "rule_engine_id", "type");
        qw.eq("rule_engine_id", ruleEngine.getId());

        List<RuleExecution> ruleExecutions = ruleExecutionService.list(qw);

        if (ObjectUtils.isEmpty(ruleExecutions)) {
            return;
        }
        for (RuleExecution ruleExecution : ruleExecutions) {
            ruleExecution.setRuleEngine(ruleEngine);
            ruleExecution.setTenantId(tenantId);
            ruleExecutionService.generateLinkage(ruleExecution);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<RuleEngine> ruleEngineList) {
        Assert.notEmpty(ruleEngineList, "参数为空");
        List<String> ids = ruleEngineList.stream().map(RuleEngine::getId).collect(Collectors.toList());
        QueryWrapper qw = new QueryWrapper();
        qw.in("rule_engine_id", ids);

        ruleTriggerService.deleteBatch(ruleTriggerService.list(qw));
        ruleConditionService.deleteBatch(ruleConditionService.list(qw));
        ruleExecutionService.deleteBatch(ruleExecutionService.list(qw));

        removeByIds(ids);
    }

    @Override
    public void updateStatus(RuleEngine ruleEngine) {
        Assert.notNull(ruleEngine, "ruleEngine 为空");
        Assert.hasLength(ruleEngine.getId(), "ruleEngine id 为空");
        Assert.notNull(ruleEngine.getStatus(), "参数 status 为空");

        RuleEngine ruleEngine2 = getById(ruleEngine.getId());
        ruleEngine2.setStatus(ruleEngine.getStatus());
        ruleEngine2.setAutoRecoverable(false);
        commonService.setModifyInfo(ruleEngine2);

        updateById(ruleEngine2);

        ruleTriggerService.updateStatusForType3ByRuleEngineChange(ruleEngine2);
    }


    @Override
    public void disableByTenantId(String tenantId) {
        UpdateWrapper<RuleEngine> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("tenant_id", tenantId);
        updateWrapper.set("status", RuleEngineConstant.STATUS_DISABLE);
        update(updateWrapper);
    }

    @Override
    public void disableByTenantIdBatch(List<String> tenantIdList) {
        UpdateWrapper<RuleEngine> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("tenant_id", tenantIdList);
        updateWrapper.set("status", RuleEngineConstant.STATUS_DISABLE);
        update(updateWrapper);
    }

    @Override
    public void enableByTenantId(String tenantId) {
        UpdateWrapper<RuleEngine> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("tenant_id", tenantId);
        updateWrapper.set("status", RuleEngineConstant.STATUS_ENABLE);
        updateWrapper.set("auto_recoverable", true);
        update(updateWrapper);
    }

    public String getCurrentUser() throws Exception {
        LinkappUser current = linkappUserContextProducer.getCurrent();
        if(current == null || StringUtils.isEmpty(current.getTenantId())){
            throw new Exception("未获取到当前用户信息");
        }
        return current.getTenantId();
    }

    /***
     * 查询改设备是否绑定
     * @param deviceCode
     */
    @Override
    public List<RuleEngine>  getDeviceCodeIsBind(String deviceCode) throws Exception {
        Assert.hasLength(deviceCode,"设备编号不能为空" );
        Device oneByDeviceCode = deviceService.findOneByDeviceCode(deviceCode);
        if(oneByDeviceCode == null){
            throw new IllegalArgumentException("设备["+deviceCode+"]不存在");
        }
        RuleEngine ruleEngine = new RuleEngine();
        ruleEngine.setTenantId(getCurrentUser());
        ruleEngine.setStatus(1);
        List<String> spacesIds = commonService.getCurrentUserSpaceIds();
        List<RuleEngine> ruleEngineList = baseMapper.getRuleEnginesExistsDeviceCode(ruleEngine, deviceCode, spacesIds);
        return ruleEngineList;
    }

    /***
     * 查询改设备是否绑定
     * @param device
     */
    private List<RuleEngine>  getDeviceCodeIsBind(Device device) throws Exception {
        Assert.notNull(device,"设备编号不能为空" );
        Assert.hasLength(device.getCode(),"设备编号不能为空" );
        List<Device> deviceList = deviceService.selectDevices(device);
        if(deviceList == null || deviceList.size()<=0){
            throw new IllegalArgumentException("设备["+device.getCode()+"]不存在");
        }
        Device oneByDeviceCode = deviceList.get(0);
        if(StringUtils.isEmpty(oneByDeviceCode.getAreaId())){
            throw new IllegalArgumentException("设备["+oneByDeviceCode.getCode()+"]未绑定空间");
        }
        BeanUtils.copyProperties(oneByDeviceCode, device);
        RuleEngine ruleEngine = new RuleEngine();
        ruleEngine.setTenantId(getCurrentUser());
        List<String> spacesIds = commonService.getCurrentUserSpaceIds();
        List<RuleEngine> ruleEngineList = baseMapper.getRuleEnginesExistsDeviceCode(ruleEngine, oneByDeviceCode.getCode(), spacesIds);
        return ruleEngineList;
    }

    /***
     * 绑定
     * @param deviceCode
     * @param phone
     * @throws Exception
     */
    @Override
//    @Transactional(rollbackFor = Exception.class)
    public void ruleEngineBindDeviceCode(String deviceCode, String phone,String deviceTypeName) throws Exception {
        Assert.hasLength(deviceCode, "设备编号不能为空" );
        Assert.hasLength(phone,"手机号不能为空" );
        Device device = new Device();
        device.setCode(deviceCode);
        List<RuleEngine> ruleEngineList = getDeviceCodeIsBind(device);
        boolean isBind=false;
        LinkappUser linkappUser = linkappUserContextProducer.getCurrent();
        if(linkappUser == null || StringUtils.isEmpty(linkappUser.getTenantId())){
            throw new Exception("未获取到当前用户信息");
        }
        if(ruleEngineList == null || ruleEngineList.size()<=0){
            //未绑定
            //查询模板
            RuleEngine ruleEngine = new RuleEngine();
            ruleEngine.setTenantId(linkappUser.getTenantId());
            ruleEngine.setName(TEMPLATEPREFIX);
            List<String> spacesIds = commonService.getCurrentUserSpaceIds();
            ruleEngineList = baseMapper.getRuleEnginesExistsDeviceCode(ruleEngine, null, spacesIds);
            isBind=false;
        }else{
            //已绑定
            isBind=true;
        }
        //执行绑定
        executeBindExists(ruleEngineList,linkappUser,device,phone,isBind,deviceTypeName);
    }

    /***
     * 执行绑定操作
     * @param ruleEngineList 模板(或者当前值)
     * @param device
     * @param phone
     */
    private void executeBindExists(List<RuleEngine> ruleEngineList,LinkappUser linkappUser,Device device,String phone,boolean isBind,String deviceTypeName) throws Exception {
        //获取联系人集合
        AlarmPersonContact alarmPersonContact = new AlarmPersonContact();
        alarmPersonContact.setPhone(phone);
        List<AlarmPersonContact> alarmPersonContacts = alarmPersonContactService.getAlarmPersonContacts(alarmPersonContact);
        if(alarmPersonContacts == null || alarmPersonContacts.size()<=0){
            //新增告警联系人
            alarmPersonContact.setPhone(phone);
            alarmPersonContact.setName(phone);
            alarmPersonContactService.addAlarmPersonContact(alarmPersonContact);
        }else{
            alarmPersonContact=alarmPersonContacts.get(0);
        }
        //保存数据
        saveRuleEngineBind(ruleEngineList,device,linkappUser,isBind,phone,alarmPersonContact);
        //发送短信
        if(StringUtils.isNotEmpty(deviceTypeName)){
            sendSmsAndSaveAlarmNotice(alarmPersonContact,deviceTypeName);
        }
    }

    /***
     * 执行绑定操作，保存数据
     * @param ruleEngineList
     * @param device
     * @param linkappUser
     * @param isBind
     * @param phone
     * @param alarmPersonContact
     * @throws Exception
     */
    private void saveRuleEngineBind(List<RuleEngine> ruleEngineList,Device device,LinkappUser linkappUser,boolean isBind,String phone,AlarmPersonContact alarmPersonContact) throws Exception {
        if(!isBind){
            //未绑定,新增
            configRuleEngine(ruleEngineList,linkappUser,phone,device,alarmPersonContact);
        }else{
            //已绑定，修改
            boolean falg=false;
            for (RuleEngine ruleEngine : ruleEngineList) {
                String name = ruleEngine.getName();
                //监测当前绑定是否是模板
                if(!StringUtils.isEmpty(name) && name.startsWith(TEMPLATEPREFIX)){
                    falg=true;
                    break;
                }
            }
            //执行修改
            updateRuleEngin(ruleEngineList,falg,linkappUser,phone,device,alarmPersonContact);
        }
    }

    /***
     * 已绑定 直接修改联系人
     * @param ruleEngines
     * @param falg
     * @param linkappUser
     * @param phone
     * @param device
     * @param alarmPersonContact
     */
    private void updateRuleEngin(List<RuleEngine> ruleEngines,boolean falg,LinkappUser linkappUser,String phone,Device device,AlarmPersonContact alarmPersonContact){
        if (ruleEngines == null || ruleEngines.size() <= 0) {
            return;
        }
        String deviceCodeSub = device.getCode().substring(device.getCode().length() - 5);
        Date date = new Date();
        //保存id关系映射
        Set<String> ruleEnginesIds = new HashSet<>();
        ruleEngines = ruleEngines.stream().map(m -> {
            ruleEnginesIds.add(m.getId());
            m.setAreaId(device.getAreaId());
            m.setSpaceId(device.getSpaceId());
            m.setStatus(1);
            m.setModifyTime(date);
            m.setModifier(linkappUser.getId() + "");
            //不是模板修改名称和描述
            if(!falg){
                String name=null;
                if(!StringUtils.isEmpty(m.getName()) && m.getName().indexOf("-") != -1){
                    String[] split = m.getName().split("-");
                    if(split.length>=1){
                        name=split[1];
                    }
                }
                m.setName(deviceCodeSub+"-"+name+"-"+phone);
                m.setDescription(device.getCode()+"-"+name+"-"+phone);
            }
            return m;
        }).collect(Collectors.toList());
        if(ruleEngines != null && ruleEngines.size() > 0){
            updateBatchById(ruleEngines);
        }
        //修改告警联系人
        updateExecutePersonContact(ruleEnginesIds,alarmPersonContact);
    }

    /***
     * 修改告警联系人
     * @param ruleEnginesIds
     * @param alarmPersonContact
     */
    private void updateExecutePersonContact(Set<String> ruleEnginesIds,AlarmPersonContact alarmPersonContact){
        if (ruleEnginesIds == null || ruleEnginesIds.size() <= 0) {
            return;
        }
        RuleExecution ruleExecution = new RuleExecution();
        ruleExecution.setRuleEngineIds(ruleEnginesIds);
        List<RuleExecution> ruleExecutions = ruleExecutionMapper.getRuleExecutions(ruleExecution);
        if (ruleExecutions == null || ruleExecutions.size() <= 0) {
            return;
        }
        Set<String> ruleExecutionIds = ruleExecutions.stream().map(RuleExecution::getId).collect(Collectors.toSet());
        List<RuleExecutionRefAlarmPersonContact> personContactList = ruleExecutionRefAlarmPersonContactMapper.findByRuleExecutionId(ruleExecutionIds);
        if(personContactList == null || personContactList.size()<=0){
            return;
        }
        RuleExecutionRefAlarmPersonContact personContact = personContactList.get(0);
        if(!alarmPersonContact.getId().equals(personContact.getAlarmPersonContactId())){
            //修改告警联系人
            List<String> ids = personContactList.stream().map(RuleExecutionRefAlarmPersonContact::getId).collect(Collectors.toList());
            if(ids != null && ids.size() > 0){
                new LambdaUpdateChainWrapper<>(ruleExecutionRefAlarmPersonContactMapper)
                        .in(RuleExecutionRefAlarmPersonContact::getId,ids)
                        .set(RuleExecutionRefAlarmPersonContact::getAlarmPersonContactId, alarmPersonContact.getId())
                        .update();
            }
        }
    }

    /***
     * 新增复制模板规则引擎
     * @param ruleEngines
     * @param linkappUser
     * @param phone
     * @param device
     */
    private void configRuleEngine(List<RuleEngine> ruleEngines,LinkappUser linkappUser,String phone,Device device,AlarmPersonContact alarmPersonContact){
        if (ruleEngines == null || ruleEngines.size() <= 0) {
            return;
        }
        String deviceCodeSub = device.getCode().substring(device.getCode().length() - 5);
        Date date = new Date();
        //保存id关系映射
        HashMap<String, String> ruleEnginesIdsMap = new HashMap<>();
        ruleEngines = ruleEngines.stream().map(m -> {
            String id = UUID.randomUUID().toString().replaceAll("-", "");
            ruleEnginesIdsMap.put(m.getId(), id);
            m.setId(id);
            m.setTenantId(linkappUser.getTenantId());
            m.setCreateTime(date);
            m.setModifyTime(date);
            m.setCreator(linkappUser.getId() + "");
            m.setModifier(linkappUser.getId() + "");
            m.setAreaId(device.getAreaId());
            m.setSpaceId(device.getSpaceId());
            String name=null;
            if(!StringUtils.isEmpty(m.getName())){
                name=m.getName().substring(TEMPLATEPREFIX.length(), m.getName().length());
            }
            m.setName(deviceCodeSub+"-"+name+"-"+phone);
            m.setDescription(device.getCode()+"-"+name+"-"+phone);
            return m;
        }).collect(Collectors.toList());

        int batchSize = 100;
        //保存规则引擎
        if (ruleEngines != null && ruleEngines.size() > 0) {
            for (int idx = 0; idx < ruleEngines.size(); idx += batchSize) {
                List<RuleEngine> list = ruleEngines.subList(idx, Math.min(ruleEngines.size(), idx + batchSize));
                baseMapper.batchInsert(list);
            }
        }
        //保存规则触发器
        saveRuleTriggers(ruleEnginesIdsMap,linkappUser,device);
        //保存规则条件器
        saveRuleCondition(ruleEnginesIdsMap,device);
        //保存规则执行器
        saveRuleExecution(ruleEnginesIdsMap, linkappUser, device,alarmPersonContact);
    }

    /***
     * 保存规则触发器
     * @param ruleEnginesIdsMap key 旧值id,value 新值id
     */
    private void saveRuleTriggers(HashMap<String, String> ruleEnginesIdsMap,LinkappUser newLinkappUser,Device device){
        if (ruleEnginesIdsMap == null || ruleEnginesIdsMap.size() <= 0) {
            return;
        }
        RuleTrigger ruleTrigger = new RuleTrigger();
        ruleTrigger.setRuleEngineIds(ruleEnginesIdsMap.keySet());
        List<RuleTrigger> ruleTriggers = ruleTriggerMapper.getRuleTriggers(ruleTrigger);
        if (ruleTriggers == null || ruleTriggers.size() <= 0) {
            return;
        }
        int size = (int) (ruleTriggers.size() * 0.75) + 1;
        HashMap<String, String> ruleTriggerIdsMap = new HashMap<>(size);
        Set<String> jobEntityIdSet = ruleTriggers.stream().filter(m -> !StringUtils.isEmpty(m.getJobEntityId())).map(m -> m.getJobEntityId()).collect(Collectors.toSet());
        Date date = new Date();
        ruleTriggers = ruleTriggers.stream().map(m -> {
            String id = UUID.randomUUID().toString().replaceAll("-", "");
            ruleTriggerIdsMap.put(m.getId(), id);
            m.setId(id);
            m.setCreateTime(date);
            m.setModifyTime(date);
            m.setRuleEngineId(ruleEnginesIdsMap.get(m.getRuleEngineId()));
            return m;
        }).collect(Collectors.toList());
        //组装定时器
        size = (int) (jobEntityIdSet.size() * 0.75) + 1;
        HashMap<String, String> jobEntityMapperMap = new HashMap<>(size);
        List<JobEntity> jobEntityList = configRuleTriggerJob(newLinkappUser, jobEntityIdSet, jobEntityMapperMap, ruleTriggerIdsMap);
        //将定时器ID组装触发器
        if (jobEntityMapperMap != null && jobEntityMapperMap.size() > 0) {
            ruleTriggers = ruleTriggers.stream().map(m -> {
                if (jobEntityMapperMap.get(m.getJobEntityId()) != null) {
                    m.setJobEntityId(jobEntityMapperMap.get(m.getJobEntityId()));
                }
                return m;
            }).collect(Collectors.toList());
        }
        //组装关联设备
        List<RuleTriggerRefDevice> ruleTriggerRefDevices = configRuleTriggerDevice(ruleTriggerIdsMap, device);
        //规则表达式
        List<IntelligentRuleExpression> intelligentRuleExpressions = configRuleTriggerExpression(ruleTriggerIdsMap);
        int batchSize = 100;
        //保存触发器
        if (ruleTriggers != null && ruleTriggers.size() > 0) {
            for (int idx = 0; idx < ruleTriggers.size(); idx += batchSize) {
                List<RuleTrigger> list = ruleTriggers.subList(idx, Math.min(ruleTriggers.size(), idx + batchSize));
                ruleTriggerMapper.batchInsert(list);
            }
        }
        //保存定时器
        if (jobEntityList != null && jobEntityList.size() > 0) {
            for (JobEntity jobEntity : jobEntityList) {
                taskSchedulerService.saveTask(jobEntity);
            }
        }
        //保存关联设备
        if (ruleTriggerRefDevices != null && ruleTriggerRefDevices.size() > 0) {
            for (int idx = 0; idx < ruleTriggerRefDevices.size(); idx += batchSize) {
                List<RuleTriggerRefDevice> list = ruleTriggerRefDevices.subList(idx, Math.min(ruleTriggerRefDevices.size(), idx + batchSize));
                ruleTriggerRefDeviceMapper.batchInsert(list);
            }
        }
        //保存规则表达式
        if (intelligentRuleExpressions != null && intelligentRuleExpressions.size() > 0) {
            for (int idx = 0; idx < intelligentRuleExpressions.size(); idx += batchSize) {
                List<IntelligentRuleExpression> list = intelligentRuleExpressions.subList(idx, Math.min(intelligentRuleExpressions.size(), idx + batchSize));
                intelligentRuleExpressionMapper.batchInsert(list);
            }
        }
    }


    /***
     * 保存规则条件器
     * @param ruleEnginesIdsMap
     * @param device
     */
    private void saveRuleCondition(HashMap<String, String> ruleEnginesIdsMap,Device device) {
        if (ruleEnginesIdsMap == null || ruleEnginesIdsMap.size() <= 0) {
            return;
        }
        RuleCondition ruleCondition = new RuleCondition();
        ruleCondition.setRuleEngineIds(ruleEnginesIdsMap.keySet());
        List<RuleCondition> ruleConditions = ruleConditionMapper.getRuleConditions(ruleCondition);
        if (ruleConditions == null || ruleConditions.size() <= 0) {
            return;
        }
        Date date = new Date();
        int size = (int) (ruleConditions.size() * 0.75) + 1;
        HashMap<String, String> ruleConditionIdsMapperMap = new HashMap<>(size);
        ruleConditions = ruleConditions.stream().map(m -> {
            String id = UUID.randomUUID().toString().replaceAll("-", "");
            ruleConditionIdsMapperMap.put(m.getId(), id);
            m.setId(id);
            m.setRuleEngineId(ruleEnginesIdsMap.get(m.getRuleEngineId()));
            m.setCreateTime(date);
            m.setModifyTime(date);
            m.setDeviceCode(device.getCode());
            return m;
        }).collect(Collectors.toList());
        //组装规则表达式
        List<IntelligentRuleExpression> intelligentRuleExpressions = configRuleConditionExpression(ruleConditionIdsMapperMap);
        int batchSize = 100;
        //保存条件器
        if (ruleConditions != null && ruleConditions.size() > 0) {
            for (int idx = 0; idx < ruleConditions.size(); idx += batchSize) {
                List<RuleCondition> list = ruleConditions.subList(idx, Math.min(ruleConditions.size(), idx + batchSize));
                ruleConditionMapper.batchInsert(list);
            }
        }
        //保存规则表达式
        if (intelligentRuleExpressions != null && intelligentRuleExpressions.size() > 0) {
            for (int idx = 0; idx < intelligentRuleExpressions.size(); idx += batchSize) {
                List<IntelligentRuleExpression> list = intelligentRuleExpressions.subList(idx, Math.min(intelligentRuleExpressions.size(), idx + batchSize));
                intelligentRuleExpressionMapper.batchInsert(list);
            }
        }

    }

    /***
     * 保存规则执行器
     * @param ruleEnginesIdsMap
     * @param deviceCode
     */
    private void saveRuleExecution(HashMap<String, String> ruleEnginesIdsMap, LinkappUser newLinkappUser,Device device,AlarmPersonContact alarmPersonContact) {
        if (ruleEnginesIdsMap == null || ruleEnginesIdsMap.size() <= 0) {
            return;
        }
        RuleExecution ruleExecution = new RuleExecution();
        ruleExecution.setRuleEngineIds(ruleEnginesIdsMap.keySet());
        List<RuleExecution> ruleExecutions = ruleExecutionMapper.getRuleExecutions(ruleExecution);
        if (ruleExecutions == null || ruleExecutions.size() <= 0) {
            return;
        }
        //获取告警模板映射关系
        Map<String, String> oldAlarmIdMap = null, newAlarmIdMap = null;
        Set<String> alarmTemplateIds = ruleExecutions.stream().filter(m -> !org.springframework.util.StringUtils.isEmpty(m.getAlarmTemplateId())).map(RuleExecution::getAlarmTemplateId).collect(Collectors.toSet());
        if (alarmTemplateIds != null && alarmTemplateIds.size() > 0) {
            //获取旧告警模板
            List<AlarmTemplate> alarmTemplateList = alarmTemplateMapper.selectBatchIds(alarmTemplateIds);
            //获取所有名称
            oldAlarmIdMap = alarmTemplateList.stream().collect(Collectors.toMap(AlarmTemplate::getId, AlarmTemplate::getName, (k1, k2) -> k2));
            AlarmTemplate alarmTemplate = new AlarmTemplate();
            alarmTemplate.setNames(new HashSet<>(oldAlarmIdMap.values()));
            alarmTemplate.setTenantId(newLinkappUser.getTenantId());
            //新告警模板
            alarmTemplateList = alarmTemplateMapper.getAlarmTemplates(alarmTemplate, newLinkappUser.getId() + "");
            newAlarmIdMap = alarmTemplateList.stream().collect(Collectors.toMap(AlarmTemplate::getName, AlarmTemplate::getId, (k1, k2) -> k2));
        }

        Date date = new Date();
        Map<String, String> finalOldAlarmIdMap = oldAlarmIdMap;
        Map<String, String> finalNewAlarmIdMap = newAlarmIdMap;
        int size = (int) (ruleExecutions.size() * 0.75) + 1;
        HashMap<String, String> ruleExecutionIdsMapperMap = new HashMap<>(size);
        ruleExecutions = ruleExecutions.stream().map(m -> {
            String id = UUID.randomUUID().toString().replaceAll("-", "");
            ruleExecutionIdsMapperMap.put(m.getId(), id);
            m.setId(id);
            m.setRuleEngineId(ruleEnginesIdsMap.get(m.getRuleEngineId()));
            m.setCreateTime(date);
            m.setModifyTime(date);
            if (!org.springframework.util.StringUtils.isEmpty(m.getAlarmTemplateId()) && finalOldAlarmIdMap != null && finalNewAlarmIdMap != null
                    && finalOldAlarmIdMap.get(m.getAlarmTemplateId()) != null) {
                m.setAlarmTemplateId(finalNewAlarmIdMap.get(finalOldAlarmIdMap.get(m.getAlarmTemplateId())));
            }
            return m;
        }).collect(Collectors.toList());
        //组装下行参数
        List<LinkageConfigRelateServiceParm> linkageConfigRelateServiceParms = configRuleExecutionServiceParm(ruleExecutionIdsMapperMap);
        //组装下行设备
        List<LinkageConfigRefDownDevice> linkageConfigRefDownDevices = configRuleExecutionServiceDevice(ruleExecutionIdsMapperMap, device);
        //组装告警联系人
        List<RuleExecutionRefAlarmPersonContact> ruleExecutionRefAlarmPersonContacts = configRuleExecutionRefAlarmPersonContact(ruleExecutionIdsMapperMap, alarmPersonContact);

        int batchSize = 100;
        //保存执行器
        if (ruleExecutions != null && ruleExecutions.size() > 0) {
            for (int idx = 0; idx < ruleExecutions.size(); idx += batchSize) {
                List<RuleExecution> list = ruleExecutions.subList(idx, Math.min(ruleExecutions.size(), idx + batchSize));
                ruleExecutionMapper.batchInsert(list);
            }
        }
        //保存下行参数
        if (linkageConfigRelateServiceParms != null && linkageConfigRelateServiceParms.size() > 0) {
            for (int idx = 0; idx < linkageConfigRelateServiceParms.size(); idx += batchSize) {
                List<LinkageConfigRelateServiceParm> list = linkageConfigRelateServiceParms.subList(idx, Math.min(linkageConfigRelateServiceParms.size(), idx + batchSize));
                linkageConfigRelateServiceParmMapper.batchInsert(list);
            }
        }
        //保存下行设备
        if (linkageConfigRefDownDevices != null && linkageConfigRefDownDevices.size() > 0) {
            for (int idx = 0; idx < linkageConfigRefDownDevices.size(); idx += batchSize) {
                List<LinkageConfigRefDownDevice> list = linkageConfigRefDownDevices.subList(idx, Math.min(linkageConfigRefDownDevices.size(), idx + batchSize));
                linkageConfigRefDownDeviceMapper.batchInsert(list);
            }
        }
        //保存告警联系人
        if(ruleExecutionRefAlarmPersonContacts != null && ruleExecutionRefAlarmPersonContacts.size() > 0){
            for (int idx = 0; idx < ruleExecutionRefAlarmPersonContacts.size(); idx += batchSize) {
                List<RuleExecutionRefAlarmPersonContact> list = ruleExecutionRefAlarmPersonContacts.subList(idx, Math.min(ruleExecutionRefAlarmPersonContacts.size(), idx + batchSize));
                ruleExecutionRefAlarmPersonContactMapper.batchInsert(list);
            }
        }
    }

    /***
     * 组装条件器-规则表达式
     * @param ruleConditionIdsMapperMap
     */
    private List<IntelligentRuleExpression> configRuleConditionExpression(HashMap<String, String> ruleConditionIdsMapperMap) {
        if (ruleConditionIdsMapperMap == null || ruleConditionIdsMapperMap.size() <= 0) {
            return null;
        }
        //查询所有关联规则
        QueryWrapper<IntelligentRuleExpression> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("rule_condition_id", ruleConditionIdsMapperMap.keySet());
        queryWrapper.eq("delete_state", 1);
        List<IntelligentRuleExpression> intelligentRuleExpressions = intelligentRuleExpressionMapper.selectList(queryWrapper);
        if (intelligentRuleExpressions == null || intelligentRuleExpressions.size() <= 0) {
            return null;
        }
        intelligentRuleExpressions = intelligentRuleExpressions.stream().map(m -> {
            m.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            m.setRuleConditionId(ruleConditionIdsMapperMap.get(m.getRuleConditionId()));
            return m;
        }).collect(Collectors.toList());
        return intelligentRuleExpressions;
    }

    /***
     *  组装触发器-规则表达式
     */
    private List<IntelligentRuleExpression> configRuleTriggerExpression(HashMap<String, String> ruleTriggerIdsMap) {
        if (ruleTriggerIdsMap == null || ruleTriggerIdsMap.size() <= 0) {
            return null;
        }
        //查询所有关联规则
        QueryWrapper<IntelligentRuleExpression> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("rule_trigger_id", ruleTriggerIdsMap.keySet());
        queryWrapper.eq("delete_state", 1);
        List<IntelligentRuleExpression> intelligentRuleExpressions = intelligentRuleExpressionMapper.selectList(queryWrapper);
        if (intelligentRuleExpressions == null || intelligentRuleExpressions.size() <= 0) {
            return null;
        }
        intelligentRuleExpressions = intelligentRuleExpressions.stream().map(m -> {
            m.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            m.setRuleTriggerId(ruleTriggerIdsMap.get(m.getRuleTriggerId()));
            return m;
        }).collect(Collectors.toList());
        return intelligentRuleExpressions;
    }

    /**
     * 组装触发器-关联设备
     */
    private List<RuleTriggerRefDevice> configRuleTriggerDevice(HashMap<String, String> ruleTriggerIdsMap,Device device) {
        if (ruleTriggerIdsMap == null || ruleTriggerIdsMap.size() <= 0) {
            return null;
        }
        //查询所有关联设备
        List<RuleTriggerRefDevice> ruleTriggerRefDeviceList = new LambdaQueryChainWrapper<>(ruleTriggerRefDeviceMapper)
                .in(RuleTriggerRefDevice::getRuleTriggerId, ruleTriggerIdsMap.keySet())
                .list();
        if (ruleTriggerRefDeviceList == null || ruleTriggerRefDeviceList.size() <= 0) {
            return null;
        }
        //替换设备,替换ruleTriggerId
        ruleTriggerRefDeviceList = ruleTriggerRefDeviceList.stream().map(m -> {
            m.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            m.setRuleTriggerId(ruleTriggerIdsMap.get(m.getRuleTriggerId()));
            m.setDeviceCode(device.getCode());
            return m;
        }).collect(Collectors.toList());
        return ruleTriggerRefDeviceList;
    }

    /***
     * 组装触发器-定时器
     * @param newLinkappUser
     * @param jobEntityIdSet
     * @param ruleTriggerJobMapperMap
     * @param ruleTriggerIdsMap
     * @return
     */
    private List<JobEntity> configRuleTriggerJob(LinkappUser newLinkappUser, Set<String> jobEntityIdSet, HashMap<String, String> ruleTriggerJobMapperMap, HashMap<String, String> ruleTriggerIdsMap) {
        if (jobEntityIdSet == null || jobEntityIdSet.size() <= 0) {
            return null;
        }
        //获取所有定时器
        List<JobEntity> jobEntityList = new LambdaQueryChainWrapper<>(jobEntityMapper)
                .in(JobEntity::getId, jobEntityIdSet)
                .list();
        if (jobEntityList == null || jobEntityList.size() <= 0) {
            return null;
        }
        Date date = new Date();
        String separator = "_";
        jobEntityList = jobEntityList.stream().map(m -> {
            String id = UUID.randomUUID().toString().replaceAll("-", "");
            ruleTriggerJobMapperMap.put(m.getId(), id);
            m.setId(id);
            //之前是存储的触发器ID，这里获取新ID存入，jobEntity.setJobName(ruleTrigger.getId());
            m.setJobName(ruleTriggerIdsMap.get(m.getJobName()));
            //替换"_"符号之后的租户ID
            if (!StringUtils.isEmpty(m.getJobGroup()) && m.getJobGroup().indexOf(separator) != -1) {
                String[] split = m.getJobGroup().split(separator);
                m.setJobGroup(split[0] + separator + newLinkappUser.getTenantId());
            } else {
                m.setJobGroup(newLinkappUser.getTenantId());
            }
            //默认禁用
            m.setJobStatus("0");
            m.setModifyTime(date);
            m.setCreateTime(date);
            return m;
        }).collect(Collectors.toList());
        return jobEntityList;
    }

    /***
     *  组装执行器-下行参数
     * @param ruleExecutionIdsMapperMap
     * @return
     */
    private List<LinkageConfigRelateServiceParm> configRuleExecutionServiceParm(HashMap<String, String> ruleExecutionIdsMapperMap) {
        if (ruleExecutionIdsMapperMap == null || ruleExecutionIdsMapperMap.size() <= 0) {
            return null;
        }
        List<LinkageConfigRelateServiceParm> serviceParmList = new LambdaQueryChainWrapper<>(linkageConfigRelateServiceParmMapper)
                .in(LinkageConfigRelateServiceParm::getRuleExecutionId, ruleExecutionIdsMapperMap.keySet())
                .list();
        if (serviceParmList == null || serviceParmList.size() <= 0) {
            return null;
        }
        HashMap<String, String> fatherSonMapperMap = new HashMap<>();
        serviceParmList = serviceParmList.stream().map(m -> {
            String id = UUID.randomUUID().toString().replaceAll("-", "");
            fatherSonMapperMap.put(m.getId(), id);
            m.setId(id);
            m.setRuleExecutionId(ruleExecutionIdsMapperMap.get(m.getRuleExecutionId()));
            return m;
        }).map(m -> {
            if (!org.springframework.util.StringUtils.isEmpty(m.getParentId())) {
                m.setParentId(ruleExecutionIdsMapperMap.get(m.getParentId()));
            }
            return m;
        }).collect(Collectors.toList());
        return serviceParmList;
    }

    /***
     * 规则执行器-配置下行设备
     * @param ruleExecutionIdsMapperMap 执行器映射
     * @param device 设备
     * @return
     */
    private List<LinkageConfigRefDownDevice> configRuleExecutionServiceDevice(HashMap<String, String> ruleExecutionIdsMapperMap,Device device) {
        if (ruleExecutionIdsMapperMap == null || ruleExecutionIdsMapperMap.size() <= 0) {
            return null;
        }
        List<LinkageConfigRefDownDevice> configRefDownDevices = new LambdaQueryChainWrapper<>(linkageConfigRefDownDeviceMapper)
                .in(LinkageConfigRefDownDevice::getRuleExecutionId, ruleExecutionIdsMapperMap.keySet())
                .list();
        if (configRefDownDevices == null || configRefDownDevices.size() <= 0) {
            return null;
        }
        configRefDownDevices = configRefDownDevices.stream().map(m -> {
            String id = UUID.randomUUID().toString().replaceAll("-", "");
            m.setId(id);
            m.setRuleExecutionId(ruleExecutionIdsMapperMap.get(m.getRuleExecutionId()));
            m.setDeviceCode(device.getCode());
            return m;
        }).collect(Collectors.toList());
        return configRefDownDevices;
    }

    /***
     * 规则执行器-配置告警联系人
     * @param ruleExecutionIdsMapperMap
     * @param alarmPersonContact
     * @return
     */
    private List<RuleExecutionRefAlarmPersonContact> configRuleExecutionRefAlarmPersonContact(HashMap<String, String> ruleExecutionIdsMapperMap,AlarmPersonContact alarmPersonContact) {
        if (ruleExecutionIdsMapperMap == null || ruleExecutionIdsMapperMap.size() <= 0) {
            return null;
        }
        List<RuleExecutionRefAlarmPersonContact> ruleExecutionRefAlarmPersonContacts = new LambdaQueryChainWrapper<>(ruleExecutionRefAlarmPersonContactMapper)
                .in(RuleExecutionRefAlarmPersonContact::getRuleExecutionId, ruleExecutionIdsMapperMap.keySet())
                .list();
        if (ruleExecutionRefAlarmPersonContacts == null || ruleExecutionRefAlarmPersonContacts.size() <= 0) {
            return null;
        }
        ruleExecutionRefAlarmPersonContacts = ruleExecutionRefAlarmPersonContacts.stream().map(m -> {
            String id = UUID.randomUUID().toString().replaceAll("-", "");
            m.setId(id);
            m.setRuleExecutionId(ruleExecutionIdsMapperMap.get(m.getRuleExecutionId()));
            m.setAlarmPersonContactId(alarmPersonContact.getId());
            return m;
        }).collect(Collectors.toList());
        return ruleExecutionRefAlarmPersonContacts;
    }

    @Override
    public void updateStatusBatch(RuleEngine ruleEngine) {
        Assert.notNull(ruleEngine, "ruleEngine 为空");
        Assert.notEmpty(ruleEngine.getIds(), "ruleEngine ids 为空");
        Assert.notNull(ruleEngine.getStatus(), "参数 status 为空");
        Collection<RuleEngine> ruleEngines = listByIds(ruleEngine.getIds());
        if(ruleEngines == null || ruleEngines.size()<=0){
            return;
        }
        LinkappUser notNullCurrent = linkappUserContextProducer.getNotNullCurrent();
        Date date = new Date();
        ruleEngines=ruleEngines.stream().map(ruleEngine2->{
            ruleEngine2.setStatus(ruleEngine.getStatus());
            ruleEngine2.setAutoRecoverable(false);
            ruleEngine2.setModifier(notNullCurrent.getId()+"");
            ruleEngine2.setModifyTime(date);
            return ruleEngine2;
        }).collect(Collectors.toList());

        updateBatchById(ruleEngines);
        for (RuleEngine ruleEngine2 : ruleEngines) {
            ruleTriggerService.updateStatusForType3ByRuleEngineChange(ruleEngine2);
        }

    }

    /**
     * 发送短信
     * @param alarmPersonContact
     */
    @Async
    public void sendSmsAndSaveAlarmNotice(AlarmPersonContact alarmPersonContact,String deviceTypeName){
        if (StringUtils.isEmpty(alarmPersonContact.getPhone())) {
            return;
        }
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");
            SendSmsRequest request = new SendSmsRequest();
            request.setPhoneNumbers(alarmPersonContact.getPhone());
            //短信模板和参数
            request.setTemplateCode(CommonConstant.SMS_227010034);
            request.setSignName(signName);
            request.setTemplateParam(getParmJsonString(deviceTypeName));
            SendSmsResponse sendSmsResponse=null;
            if (null == acsClient) {
                return;
            }
            try {
                sendSmsResponse = acsClient.getAcsResponse(request);
            } catch (ClientException e) {
                log.error("分子产品-天然气监测发送短信发生异常 ：" + e.getMessage());
                e.printStackTrace();
            }
            if (null != sendSmsResponse && !"OK".equalsIgnoreCase(sendSmsResponse.getCode())) {
                log.error("分子产品-天然气监测发送短信发生异常:param："+JSONObject.toJSONString(request.getBodyParameters())+";error："+sendSmsResponse.getMessage());
            }
    }

   private static String getParmJsonString(String deviceTypeName) {
        JSONObject param = new JSONObject();
        param.put("deviceTypeName",deviceTypeName);
        return param.toString();
    }
}

